local Opts = nibWatchFrameAdv_Cfg

local nWFA = CreateFrame("Frame")
local EventsRegistered

local WF;
local OrigWFSetPoint, OrigWFClearAllPoints;
local origWFHighlight;
local WFColorsHooked = false;

-- Hide Quest Tracker based on zone
function nWFA.UpdateHideState()
	if not WF then WF = _G["WatchFrame"]; end
	
	local Inst, InstType = IsInInstance();
	local Hide = false;
	if Opts.hidden.enabled and Inst then
		if (InstType == "pvp" and Opts.hidden.hide.pvp) then			-- Battlegrounds
			Hide = true;
		elseif (InstType == "arena" and Opts.hidden.hide.arena) then	-- Arena
			Hide = true;
		elseif (InstType == "party" and Opts.hidden.hide.party) then	-- 5 Man Dungeons
			Hide = true;
		elseif (InstType == "raid" and Opts.hidden.hide.raid) then	-- Raid Dungeons
			Hide = true;
		end
	end
	if Hide then WF:Hide() else WF:Show() end
end

-- Collapse Quest Tracker based on zone
function nWFA.UpdateCollapseState()
	if not WF then WF = _G["WatchFrame"]; end
	if not Opts.hidden.enabled then return end
	
	local Inst, InstType = IsInInstance();
	local Collapsed = false;
	if Inst then
		if (InstType == "pvp" and Opts.hidden.collapse.pvp) then			-- Battlegrounds
			Collapsed = true;
		elseif (InstType == "arena" and Opts.hidden.collapse.arena) then	-- Arena
			Collapsed = true;
		elseif (InstType == "party" and Opts.hidden.collapse.party) then	-- 5 Man Dungeons
			Collapsed = true;
		elseif (InstType == "raid" and Opts.hidden.collapse.raid) then	-- Raid Dungeons
			Collapsed = true;
		end
	end
	
	if Collapsed then
		WF.userCollapsed = true;
		WatchFrame_Collapse(WF);
	else
		WF.userCollapsed = false;
		WatchFrame_Expand(WF);
	end	
end

-- Position the Quest Tracker
function nWFA.UpdatePosition()
	if not WF then WF = _G["WatchFrame"]; end
	if not Opts.position.enabled then return end
	
	if not OrigWFSetPoint then
		OrigWFSetPoint = WF.SetPoint;
	else
		WF.SetPoint = OrigWFSetPoint;
	end
	if not OrigWFClearAllPoints then
		OrigWFClearAllPoints = WF.ClearAllPoints;
	else
		WF.ClearAllPoints = OrigWFClearAllPoints;
	end
	
	WF:ClearAllPoints();
	WF:SetPoint(Opts.position.anchor, "UIParent", Opts.position.anchor, Opts.position.x, Opts.position.y);
	WF:SetHeight(UIParent:GetHeight() - Opts.position.negheightofs);
	WF.ClearAllPoints = function() end
	WF.SetPoint = function() end
end

-- Udate WatchFrame styling
function nWFA.UpdateStyle()
	local WFT = _G["WatchFrameTitle"];
	
	-- Header
	if Opts.colors.enabled then
		if not WFColorsHooked then nWFA.HookWFColors(); end
		if WFT then	
			WFT:SetTextColor(Opts.colors.title.r, Opts.colors.title.g, Opts.colors.title.b);
		end
	end
	
	-- Update all lines
	for i = 1, #WATCHFRAME_LINKBUTTONS do
		WatchFrameLinkButtonTemplate_Highlight(WATCHFRAME_LINKBUTTONS[i], false);
	end
	
	-- Button
	if Opts.hidecollapsebutton then
		WatchFrameCollapseExpandButton:Hide()
		WatchFrameCollapseExpandButton.Show = function() end
	end
end

-- Font Updates
function nWFA.HookFont()
	local WFT = _G["WatchFrameTitle"]
	
	local Flag
	if Opts.font.outline then Flag = "OUTLINE" else Flag = "None" end
	
	WFT:SetFont("Interface\\addons\\sharedmedia\\fonts\\font.ttf", 8, "OUTLINEMONOCHROME")
	WFT:SetShadowOffset(0,0)
	WFT:SetAlpha(0)
	
	hooksecurefunc("WatchFrame_SetLine", function(line, anchor, verticalOffset, isHeader, text, dash, hasItem, isComplete)
		line.text:SetFont("Interface\\addons\\sharedmedia\\fonts\\font.ttf", 8, "OUTLINEMONOCHROME")
		line.text:SetShadowOffset(0,0)
		if line.dash then
			line.dash:SetFont(GameFontNormalSmall:GetFont(), Opts.font.size, Flag)
		end
	end)
end

-- Hook into / replace WatchFrame functions for Colors
function nWFA.HookWFColors()
	-- Colors
	if Opts.colors.enabled then
		local lc = {
			n = {h = Opts.colors.lines.normal.header, o = Opts.colors.lines.normal.objectives},
			h = {h = Opts.colors.lines.highlight.header, o = Opts.colors.lines.highlight.objectives},
		};
		
		-- Hook into SetLine to change color of lines	
		hooksecurefunc("WatchFrame_SetLine", function(line, anchor, verticalOffset, isHeader, text, dash, hasItem, isComplete)
			if isHeader then 
				line.text:SetTextColor(lc.n.h.r, lc.n.h.g, lc.n.h.b);
			else
				line.text:SetTextColor(lc.n.o.r, lc.n.o.g, lc.n.o.b);
			end
		end)
		
		-- Replace Highlight function
		WatchFrameLinkButtonTemplate_Highlight = function(self, onEnter)
			local line;
			for index = self.startLine, self.lastLine do
				line = self.lines[index];
				if line then
					if index == self.startLine then
						-- header
						if onEnter then
							line.text:SetTextColor(lc.h.h.r, lc.h.h.g, lc.h.h.b);
						else
							line.text:SetTextColor(lc.n.h.r, lc.n.h.g, lc.n.h.b);
						end
					else
						if onEnter then
							line.text:SetTextColor(lc.h.o.r, lc.h.o.g, lc.h.o.b);
							line.dash:SetTextColor(lc.h.o.r, lc.h.o.g, lc.h.o.b);
						else
							line.text:SetTextColor(lc.n.o.r, lc.n.o.g, lc.n.o.b);
							line.dash:SetTextColor(lc.n.o.r, lc.n.o.g, lc.n.o.b);
						end
					end
				end
			end
		end
		WFColorsHooked = true
	end
end

----
function nWFA.PLAYER_ENTERING_WORLD()
	nWFA.UpdateCollapseState()
	nWFA.UpdateHideState()
end

function nWFA.PLAYER_LOGIN()
	nWFA.HookWFColors()
	nWFA.UpdatePosition()
	nWFA.UpdateStyle()
	nWFA.HookFont()
end

local function EventHandler(self, event)
	if event == "PLAYER_LOGIN" then
		nWFA.PLAYER_LOGIN()
	elseif event == "PLAYER_ENTERING_WORLD" then
		nWFA.PLAYER_ENTERING_WORLD()
	end
end
nWFA:RegisterEvent("PLAYER_LOGIN")
nWFA:RegisterEvent("PLAYER_ENTERING_WORLD")
nWFA:SetScript("OnEvent", EventHandler)